package com.central.apps.handler.project;

import com.central.app.common.base.BaseHandler;
import com.central.app.service.HandlerService;
import com.central.apps.common.constant.BizConstant;
import com.central.apps.service.BudgetTempleteService;
import com.central.bizcommon.model.flow.FlowNode;
import com.central.bizcommon.model.flow.FlowOpinion;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 处理预算管理业务逻辑
 *
 * @author lidachao
 * @date 2023/3/22
 */
@Component
@Slf4j
public class ProjectBudgetHandler extends BaseHandler {

    @Autowired
    private HandlerService handlerService;
    @Autowired
    private BudgetTempleteService budgetTempleteService;

    @Override
    public String validateSave(String app, String objName, Map<String, Object> data) throws Exception {
        if ("gq_propublicbudget".equals(objName)) {
            Integer id = MapUtils.getInteger(data, "id");
            Integer proId = MapUtils.getInteger(data, "proid");
            Integer pbiId = MapUtils.getInteger(data, "pbiid");
            String year = MapUtils.getString(data, "year");

            StringBuilder sbSql = new StringBuilder();
            sbSql.append("select id from gq_propublicbudget where status != '已作废' and year = '").append(year)
                    .append("' and pbiid = ").append(pbiId).append(" and proid = ").append(proId);
            if (id != null) {
                sbSql.append(" and id != ").append(id);
            }

            // 查询是否已经存在预算申请
            List<Map<String, Object>> list = handlerService.findBySql(sbSql.toString());

            if (CollectionUtils.isNotEmpty(list)) {
                String budgetCategory = MapUtils.getString(data, "budgetcategory");
                return "已经存在" + budgetCategory + year + "公共预算申请数据, 不能再新建数据!";
            }
        }

        return null;
    }

    @Override
    public void beforSave(String app, String objName, Map<String, Object> data, boolean isUpdate) throws Exception {
        if ("gq_propublicbudget".equals(objName)) {
            Integer pbId = MapUtils.getInteger(data, "id");
            Integer pbiId = MapUtils.getInteger(data, "pbiid");

            if (isUpdate) {
                Map<String, Object> map = handlerService.findOneBySql("select pbiid from gq_propublicbudget where id = " + pbId);
                Integer oldPbiId = MapUtils.getInteger(map, "pbiid");

                if (!pbiId.equals(oldPbiId)) {
                    // 删除历史数据
                    delBudgetDtlItem(pbId);
                }
            }
        }
    }

    @Override
    public void afterSave(String app, String objName, Map<String, Object> data, boolean isUpdate) throws Exception {
        if ("gq_propublicbudget".equals(objName)) {
            Integer pbId = MapUtils.getInteger(data, "id");

            List<Map<String, Object>> list = handlerService.findBySql("select pbiid from gq_ppbudget where pbid = " + pbId);
            if (CollectionUtils.isEmpty(list)) {
                Integer pbiId = MapUtils.getInteger(data, "pbiid");
                String year = MapUtils.getString(data, "year");
                String subjectNo = MapUtils.getString(data, "subjectno");
                Integer proId = MapUtils.getInteger(data, "proid");
                String bugdetCategory = MapUtils.getString(data, "bugdetcategory");
                // 添加顶级预算项明细
                addBudgetTopDtlItem(pbId, year, proId, subjectNo, pbiId, bugdetCategory);
            }
        }
    }

    @Override
    public String beforeExcuteFlow(String app, Long id, FlowNode flowNode, FlowOpinion op) throws Exception {
        if(flowNode.getId().equals("capture")) {
            List<Map<String, Object>> list = handlerService.findBySql("select * from gq_ppbudget where pbid = " + id);

            if (CollectionUtils.isEmpty(list)) {
                return "请维护预算明细数据!";
            }
        }
        return null;
    }

    /**
     * 删除预算明细项
     *
     * @param pbId
     */
    private void delBudgetDtlItem(Integer pbId) {
        handlerService.updateBySql("delete from gq_ppbudget where pbid = " + pbId);
        handlerService.updateBySql("delete from gq_pbdetailtemplete where pbid = " + pbId);
    }

    /**
     * 添加预算明细项
     *
     * @param pbId
     * @param proId
     * @param subjectNo
     * @param pbiId
     * @param budgetItem
     * @throws Exception
     */
    private void addBudgetTopDtlItem(Integer pbId, String year, Integer proId, String subjectNo, Integer pbiId, String budgetItem) throws Exception {
        // 查询顶级预算配置项
        Map<String, Object> map = handlerService.findOneBySql("select * from gq_probugdetcfg where id = " + pbiId + " order by sort");
        String tempName = MapUtils.getString(map, "tempname");

        if (StringUtils.isNotEmpty(tempName)) {
            // 递归预算模版信息
            addTempDtlItem(tempName, pbId, year, proId, subjectNo, pbiId, budgetItem);
        } else {
            // 递归调用添加预算项
            addBudgetDtlItem(pbId, year, proId, subjectNo, pbiId, budgetItem);
        }
    }

    /**
     * 添加预算明细项
     *
     * @param pbId
     * @param proId
     * @param subjectNo
     * @param pbiId
     * @param budgetItem
     * @throws Exception
     */
    private void addBudgetDtlItem(Integer pbId, String year, Integer proId, String subjectNo, Integer pbiId, String budgetItem) throws Exception {
        // 查询预算配置项
        List<Map<String, Object>> list = handlerService.findBySql("select * from gq_probugdetcfg where parentid = " + pbiId + " order by sort");

        if (CollectionUtils.isEmpty(list)) {
            return;
        }

        // 组织并插入预算明细项信息
        for (Map<String, Object> map : list) {
            Integer itemId = MapUtils.getInteger(map, "id");
            String itemNum = MapUtils.getString(map, "itemnum");
            String itemDesc = MapUtils.getString(map, "itemdesc");
            String isCollect = MapUtils.getString(map, "iscollect");
            String isFill = MapUtils.getString(map, "isfill");
            String isCalculate = MapUtils.getString(map, "iscalculate");
            String calFormula = MapUtils.getString(map, "calformula");
            String remarks = MapUtils.getString(map, "remarks");
            String tempName = MapUtils.getString(map, "tempname");

            Map<String, Object> addMap = new HashMap<>();
            addMap.put("pbid", pbId);
            addMap.put("year", year);
            addMap.put("proid", proId);
            addMap.put("subjectno", subjectNo);
            addMap.put("pbiid", itemId);
            addMap.put("pbinum", itemNum);
            addMap.put("budgetitem", itemDesc);
            addMap.put("pbiparentid", pbiId);
            addMap.put("pbudgetitem", budgetItem);
            addMap.put("iscollect", isCollect);
            addMap.put("isfill", isFill);
            addMap.put("iscalculate", isCalculate);
            addMap.put("calformula", calFormula);
            addMap.put("bugdetamt", 0);
            addMap.put("availableamt", 0);
            addMap.put("usedamt", 0);
            addMap.put("taxrate", 1);
            addMap.put("remarks", remarks);
            addMap.put("tempname", tempName);

            handlerService.insert("gq_ppbudget", addMap);

            if (StringUtils.isNotEmpty(tempName)) {
                // 递归预算模版信息
                addTempDtlItem(tempName, pbId, year, proId, subjectNo, itemId, itemDesc);
            } else {
                // 递归调用添加预算项
                addBudgetDtlItem(pbId, year, proId, subjectNo, itemId, itemDesc);
            }
        }
    }

    /**
     * 添加预算模版明细项
     *
     * @param tempName
     * @param pbId
     * @param proId
     * @param subjectNo
     * @param pbiId
     * @param budgetItem
     * @throws Exception
     */
    private void addTempDtlItem(String tempName, Integer pbId, String year, Integer proId, String subjectNo, Integer pbiId, String budgetItem) throws Exception {
        Map<String, Object> params = new HashMap<>();
        params.put(BizConstant.PB_ID, pbId);
        params.put(BizConstant.PB_YEAR, year);
        params.put(BizConstant.PRO_ID, proId);
        params.put(BizConstant.SUBJECT_NO, subjectNo);
        params.put(BizConstant.PBI_ID, pbiId);
        params.put(BizConstant.PBI_DESC, budgetItem);

        budgetTempleteService.addPrependData(tempName, pbiId, params);
    }
}
